package com.vpx.server.framework.base;

import com.alibaba.fastjson.JSON;
import com.vpx.server.framework.utils.ToString;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.List;

/**
 * @author xx
 * @title: vpx
 * @module 
 * @description: 
 * @date 
 */
@ApiModel
public class ReplyJson<T> implements Serializable {
    private final static Logger logger = LoggerFactory.getLogger(ReplyJson.class);

    private static final long serialVersionUID = 6681841768477488492L;

    private static final String DEFAULT_SUCCESS_CODE = "1";

    private static final String DEFAULT_FAIL_CODE = "0";

    public static final String UNLOGIN_CODE = "-1";

    public static final String UNAUTH_CODE = "-2";

    public static final String UNLOGIN_CODE_MESSAGE = "登录失效";

    public static final String UNAUTH_CODE_MESSAGE = "未授权";

    private static final String DEFAULT_SUCCESS_MESSAGE = "操作成功";

    private static final String DEFAULT_FAIL_MESSAGE = "操作失败";

    private static final String DEFAULT_EXCEPTION_MESSAGE = "服务器繁忙，请稍后重试";

    /**
     * 状态
     */
    @ApiModelProperty("状态")
    private boolean success = false;

    /**
     * 结果码
     */
    @ApiModelProperty("结果码")
    private String code;

    /**
     * 应答信息
     */
    @ApiModelProperty("应答信息")
    private String message;

    /**
     * 返回详情数据
     */
    @ApiModelProperty("返回详情数据")
    private T data;

    public ReplyJson(boolean success, String code, String message, T data) {
        this.code = code;
        this.success = success;
        if (hasException(message) && !success) {
            this.message = DEFAULT_EXCEPTION_MESSAGE;
        } else {
            this.message = message;
        }
        this.data = data;
        logger.info("Ajax请求应答>>>状态：{}，code：{}，message：{}，data：{}", success, code, message, data);
    }

    public static boolean hasException(String message) {
        return StringUtils.hasText(message) && message.contains("Exception");
    }

    /**
     * 返回成功信息到客户端
     *
     * @param code    返回码
     * @param message 描述信息
     * @param data    还回的数据对象
     * @return
     */
    public static ReplyJson success(String code, String message, Object data) {
        return new ReplyJson(true, code, message, data);
    }

    /**
     * 返回成功信息到客户端
     *
     * @param message 描述信息
     * @param data    还回的数据对象
     * @return
     */
    public static ReplyJson success(String message, Object data) {
        return success(DEFAULT_SUCCESS_CODE, message, data);
    }

    /**
     * 返回成功信息到客户端 描述信息固定为<code>DEFAULT_SUCCESS_MESSAGE</code>
     *
     * @param data 返回的数据对象
     * @return
     */
    public static ReplyJson success(Object data) {
        return success(DEFAULT_SUCCESS_MESSAGE, data);
    }

    /**
     * 返回成功信息到客户端 描述信息固定为<code>DEFAULT_SUCCESS_MESSAGE</code>
     *
     * @param message 返回的描述信息
     * @return
     */
    public static ReplyJson success(String message) {
        return success(message, null);
    }

    /**
     * 返回失败信息到客户端 描述信息固定为<code>DEFAULT_fail_MESSAGE</code>
     *
     * @param data 返回的数据对象
     * @return
     */
    public static ReplyJson fail(Object data) {
        return fail(DEFAULT_FAIL_MESSAGE, data);
    }

    public static ReplyJson systemError() {
        return fail(DEFAULT_EXCEPTION_MESSAGE);
    }

    /**
     * 返回成功信息到客户端
     *
     * @param message 描述信息
     * @param data    还回的数据对象
     * @return
     */
    public static ReplyJson fail(String message, Object data) {
        return fail(DEFAULT_FAIL_CODE, message, data);
    }

    /**
     * 返回成功信息到客户端
     *
     * @param message 描述信息
     * @return
     */
    public static ReplyJson fail(String message) {
        return fail(DEFAULT_FAIL_CODE, message, null);
    }

    /**
     * 返回成功信息到客户端
     *
     * @param code    返回码
     * @param message 描述信息
     * @param data    还回的数据对象
     * @return
     */
    public static ReplyJson fail(String code, String message, Object data) {
        return new ReplyJson(false, code, message, data);
    }

    /**
     * @param result  业务返回对象
     * @param voClazz 返回类型
     * @param <VO>    与 <Result> 的属性值必须保持一致,属性对象可以不是同一个,但是对应的属性名必须一致
     *                举例:
     *                Result: private PageEntity<A> pageInfo;
     *                VO: private PageVO<B> pageInfo;
     *                其中的pageInfo保持一致,A和B中的属性名也必须保持一致,就可以实现属性转换了
     * @return T
     */
    public static <VO extends Base, Result extends BaseResult> ReplyJson<VO> success(Result result, Class<VO> voClazz) {
        String dataJson = JSON.toJSONString(result);
        VO vo = JSON.parseObject(dataJson, voClazz);
        return success(vo);
    }

    /**
     * @param voClazz 返回类型
     * @param <VO>    与 <Result> 的属性值必须保持一致,属性对象可以不是同一个,但是对应的属性名必须一致
     *                举例:
     *                Result: private PageEntity<A> pageInfo;
     *                VO: private PageVO<B> pageInfo;
     *                其中的pageInfo保持一致,A和B中的属性名也必须保持一致,就可以实现属性转换了
     * @return T
     */
    public static <VO extends Base, Result extends BaseResult> ReplyJson<List<VO>> success(List list, Class voClazz) {
        String dataJson = JSON.toJSONString(list);
        List voList = JSON.parseArray(dataJson, voClazz);
        return success(voList);
    }


    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return ToString.toString(this);
    }
}
